package com.comtop.topcloud.device.util;


import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;

public class InfluxDBQueryBuilder {

    /**
     * 将 LocalDateTime 转换为 Unix 时间戳（秒）
     */
    public static long toEpochSecond(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.UTC).getEpochSecond();
    }

    /**
     * 根据传入的条件字符串生成相应的正则表达式查询语句
     *
     * @param condition 查询条件（可以是%Device%形式）
     * @return 转换后的正则表达式查询条件
     */
    public static String generateRegexCondition(String condition) {
        if (condition == null) {
            return null;
        }

        // 如果包含 % 符号，分别处理
        if (condition.startsWith("%") && condition.endsWith("%")) {
            return "=~ /" + condition.substring(1, condition.length() - 1) + "/"; // 中间包含%，转换为 =~ /xxx/
        } else if (condition.startsWith("%")) {
            return "=~ /" + condition.substring(1) + "$/"; // 以%开头，转换为 =~ /xxx$/
        } else if (condition.endsWith("%")) {
            return "=~ /^" + condition.substring(0, condition.length() - 1) + "/"; // 以%结尾，转换为 =~ /^xxx/
        } else {
            return "== \"" + condition + "\""; // 普通匹配，转换为 == "xxx"
        }
    }

    /**
     * 构建InfluxDB查询语句（传入时间范围）
     *
     * @param bucket        数据库名称
     * @param measurement   测量名称
     * @param timeRangeStart 开始时间范围（LocalDateTime类型）
     * @param timeRangeStop 结束时间范围（LocalDateTime类型）
     * @param conditions    查询条件
     * @return              构建的查询语句
     */
    public static String buildQuery(String bucket, String measurement,
                                    LocalDateTime timeRangeStart, LocalDateTime timeRangeStop,
                                    Map<String, String> conditions) {

        // 开始构建基本的查询语句
        StringBuilder fluxQuery = new StringBuilder();

        // from bucket
        fluxQuery.append("from(bucket: \"").append(bucket).append("\")\n");

        // range filter (timeRangeStart, timeRangeStop) 转换为时间戳
        if (timeRangeStart != null && timeRangeStop != null) {
            fluxQuery.append("  |> range(start: ").append(toEpochSecond(timeRangeStart))
                    .append(", stop: ").append(toEpochSecond(timeRangeStop)).append(")\n");
        } else if (timeRangeStart != null) {
            fluxQuery.append("  |> range(start: ").append(toEpochSecond(timeRangeStart)).append(")\n");
        } else if (timeRangeStop != null) {
            fluxQuery.append("  |> range(start: 0,stop: ").append(toEpochSecond(timeRangeStop)).append(")\n");
        } else {
            fluxQuery.append("  |> range(start: 0)\n");
        }

        // filter by measurement
        fluxQuery.append("  |> filter(fn: (r) => r[\"_measurement\"] == \"").append(measurement).append("\")\n");

        // 添加其他条件（如果有）
        if (conditions != null && !conditions.isEmpty()) {
            for (Map.Entry<String, String> entry : conditions.entrySet()) {
                String condition = entry.getValue();
                String regexCondition = generateRegexCondition(condition);  // 生成正则表达式的查询条件
                fluxQuery.append("  |> filter(fn: (r) => r[\"")
                        .append(entry.getKey())
                        .append("\"] ").append(regexCondition)
                        .append(")\n");
            }
        }

        // pivot
        fluxQuery.append("  |> pivot(rowKey:[\"_time\"], columnKey:[\"_field\"], valueColumn: \"_value\")");

        return fluxQuery.toString();
    }

    /**
     * 构建InfluxDB查询语句（没有时间范围）
     *
     * @param bucket        数据库名称
     * @param measurement   测量名称
     * @param conditions    查询条件
     * @return              构建的查询语句
     */
    public static String buildQuery(String bucket, String measurement, Map<String, String> conditions) {
        return buildQuery(bucket, measurement, null, null, conditions);
    }

    /**
     * 构建InfluxDB查询语句（仅传入时间范围）
     *
     * @param bucket        数据库名称
     * @param measurement   测量名称
     * @param start         开始时间（LocalDateTime类型）
     * @param stop          结束时间（LocalDateTime类型）
     * @return              构建的查询语句
     */
    public static String buildQuery(String bucket, String measurement, LocalDateTime start, LocalDateTime stop) {
        return buildQuery(bucket, measurement, start, stop, null);
    }

    /**
     * 构建InfluxDB查询语句（无条件、无时间范围）
     *
     * @param bucket        数据库名称
     * @param measurement   测量名称
     * @return              构建的查询语句
     */
    public static String buildQuery(String bucket, String measurement) {
        return buildQuery(bucket, measurement, null, null, null);
    }
}
